home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1994 October / Macformat17.cdr / Shareware City / Developers / shutdown-fx-201-c / sfx ƒ / sfx control app ƒ / sfx code ƒ / debinhex.c < prev    next >
Text File  |  1994-07-11  |  6KB  |  256 lines

  1. /**********************************************************************\
  2.  
  3. File:        debinhex.c
  4.  
  5. Purpose:    This module handles all the blood and guts of actual
  6.             deBinHexing.
  7.  
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12.  
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with this program in a file named "GNU General Public License".
  20. If not, write to the Free Software Foundation, 675 Mass Ave,
  21. Cambridge, MA 02139, USA.
  22.  
  23. \**********************************************************************/
  24.  
  25. #include "file management.h"
  26. #include "debinhex dispatch.h"
  27. #include "debinhex.h"
  28. #include "util.h"
  29.  
  30. /* all these globals are internal to debinhex.c */
  31. unsigned char    bstr[64];            /* table of binhex characters with 6-bit index */
  32. unsigned short    crc;                /* binhex checksum */
  33. unsigned char    bufferChar;            /* last char read */
  34. unsigned char    runLenLength;        /* run-len encoding current length */
  35. char            slop;                /* bits we haven't dealt with yet */
  36. short            phase;                /* how many bits we need */
  37.  
  38. Ptr                dbhRaw;                /* raw binhexed data, read in from disk */
  39. unsigned long    dbhSize;            /* actual size of dbhRaw buffer */
  40. unsigned long    dbhPos;                /* where we are in dbhRaw in processing */
  41. unsigned long    dbhTotal;            /* total # of bytes in dbhRaw that contain data */
  42. unsigned char    dbhValues[256];        /* table of values for debinhexing */
  43. Boolean            lookingForRunLen;    /* whether we can handle run-len right now */
  44. Boolean            nowGettingRunLen;    /* whether we are getting a run-len length byte now */
  45.  
  46. enum
  47. {
  48.     no_bits = 0,
  49.     two_bits,
  50.     four_bits,
  51.     six_bits
  52. };
  53.  
  54. void InitDeBinHex(void)
  55. {
  56.     short            i;
  57.     
  58.     Mymemcpy((Ptr)bstr, (Ptr)((long)(*GetString(BINHEX_VALUES_STRING))+1), 64);
  59.     Mymemset((Ptr)dbhValues, 0xff, 256); /* init all values to bad ones */
  60.     for (i=0; i<64; i++)
  61.         dbhValues[bstr[i]]=i; /* put in valid binhex values */
  62.     dbhValues[9]=dbhValues[10]=dbhValues[13]=dbhValues[23]=0x80; /* whitespace */
  63.     
  64.     dbhSize=BINHEX_BUFFER_LENGTH;
  65.     dbhRaw=NewPtr(dbhSize);
  66.     dbhPos=-1L;                    /* need more binhex data from disk */
  67.     lookingForRunLen=FALSE;
  68.     nowGettingRunLen=FALSE;
  69.     phase=no_bits;
  70.     crc=0;
  71.     runLenLength=0x00;
  72. }
  73.  
  74. void EndDeBinHex(void)
  75. {
  76.     DisposePtr(dbhRaw);
  77. }
  78.  
  79. enum ErrorTypes GetNBytes(short inputRefNum, Ptr outBuf, unsigned long n)
  80. {
  81.     unsigned long    off;
  82.     enum ErrorTypes    resultCode;
  83.     
  84.     off=0L;
  85.     while (off<n)
  86.     {
  87.         if (dbhPos==-1L)
  88.         {
  89.             resultCode=ReadInputFile(inputRefNum, dbhRaw, dbhSize, &dbhTotal);
  90.             if (resultCode!=allsWell)
  91.                 return resultCode;
  92.             dbhPos=0L;
  93.         }
  94.         resultCode=GetByteFromBuffer((unsigned char*)((long)outBuf+off));
  95.         if (resultCode==allsWell)
  96.             off++;
  97.         else if ((resultCode==kBinHexErr) && (off==n-1))
  98.             resultCode=FlushBuffer((unsigned char*)((long)outBuf+(off++)));
  99.         if (resultCode==kBinHexErr)
  100.             return resultCode;
  101.         if (resultCode==kNeedMoreBinHexErr)
  102.             dbhPos=-1L;
  103.     }
  104.     return allsWell;
  105. }
  106.  
  107. enum ErrorTypes FlushBuffer(unsigned char *outputChar)
  108. {
  109.     *outputChar=bufferChar;
  110.     if (runLenLength!=0x00)
  111.         runLenLength--;
  112.     return allsWell;
  113. }
  114.  
  115. enum ErrorTypes GetByteFromBuffer(unsigned char *outputChar)
  116. {
  117.     unsigned char        thisByte;
  118.     enum ErrorTypes        resultCode;
  119.     
  120.     if (runLenLength!=0x00)
  121.     {
  122.         *outputChar=bufferChar;
  123.         runLenLength--;
  124.         return allsWell;
  125.     }
  126.  
  127.     if (!lookingForRunLen)
  128.     {
  129.         if (!nowGettingRunLen)
  130.         {
  131.             resultCode=ExtractByteFromBinHex(&thisByte);
  132.             if (resultCode!=allsWell)
  133.                 return resultCode;
  134.         }
  135.         else
  136.             thisByte=0x90;
  137.         
  138.         if (thisByte==0x90)
  139.         {
  140.             nowGettingRunLen=TRUE;
  141.             resultCode=ExtractByteFromBinHex(&runLenLength);
  142.             if (resultCode!=allsWell)
  143.                 return resultCode;
  144.             nowGettingRunLen=FALSE;
  145.         }
  146.         bufferChar=thisByte;
  147.         lookingForRunLen=TRUE;
  148.     }
  149.  
  150.     if (!nowGettingRunLen)
  151.     {
  152.         resultCode=ExtractByteFromBinHex(&thisByte);
  153.         if (resultCode!=allsWell)
  154.             return resultCode;
  155.     }
  156.     else
  157.         thisByte=0x90;
  158.     
  159.     if (thisByte==0x90)
  160.     {
  161.         nowGettingRunLen=TRUE;
  162.         resultCode=ExtractByteFromBinHex(&runLenLength);
  163.         if (resultCode!=allsWell)
  164.             return resultCode;
  165.         nowGettingRunLen=FALSE;
  166.         if (runLenLength!=0x00)
  167.         {
  168.             lookingForRunLen=FALSE;
  169.             *outputChar=bufferChar;
  170.             runLenLength--;
  171.             return allsWell;
  172.         }
  173.         else
  174.         {
  175.             *outputChar=bufferChar;
  176.             bufferChar=thisByte;
  177.             return allsWell;
  178.         }
  179.     }
  180.     else
  181.     {
  182.         *outputChar=bufferChar;
  183.         bufferChar=thisByte;
  184.         return allsWell;
  185.     }
  186. }
  187.  
  188. enum ErrorTypes ExtractByteFromBinHex(unsigned char *outputChar)
  189. {
  190.     unsigned char    thisChar;
  191.     
  192.     while (1)
  193.     {
  194.         if (dbhPos==dbhTotal)
  195.             return kNeedMoreBinHexErr;
  196.         thisChar=dbhValues[*((unsigned char*)((long)dbhRaw+(dbhPos++)))];
  197.         if (thisChar==0xff) /* invalid binhex */
  198.             return kBinHexErr;
  199.         if (thisChar!=0x80) /* only process non-whitespace */
  200.         {
  201.             switch (phase)
  202.             {
  203.                 case no_bits:
  204.                     slop=thisChar&0x3f;
  205.                     phase=two_bits;
  206.                     break;
  207.                 case two_bits:
  208.                     *outputChar=(slop<<2)|(thisChar&0x30)>>4;
  209.                     slop=thisChar&0x0f;
  210.                     phase=four_bits;
  211.                     return allsWell;
  212.                     break;
  213.                 case four_bits:
  214.                     *outputChar=(slop<<4)|(thisChar&0x3c)>>2;
  215.                     slop=thisChar&0x03;
  216.                     phase=six_bits;
  217.                     return allsWell;
  218.                     break;
  219.                 case six_bits:
  220.                     *outputChar=(slop<<6)|(thisChar&0x3f);
  221.                     phase=no_bits;
  222.                     return allsWell;
  223.             }
  224.         }
  225.     }
  226. }
  227.  
  228. short BinHexChecksum(Ptr buffer, unsigned long len, Boolean StartOver)
  229. {
  230.     unsigned long    off;
  231.     
  232.     if (StartOver)
  233.         crc=0;
  234.     
  235.     off=0L;
  236.     while (off<len)
  237.         CalcCRC(&crc, *((unsigned char*)((long)buffer+(off++))));
  238.  
  239.     return crc;
  240. }
  241.  
  242. void CalcCRC(unsigned short *crc, unsigned short v)
  243. {
  244.     short            i;
  245.     Boolean        temp;
  246.     
  247.     for (i=1; i<=8; i++)
  248.     {
  249.         temp=((*crc)&0x8000)!=0;
  250.         *crc=((*crc)<<1)|((v>>7)&0x0001);
  251.         if (temp)
  252.             (*crc)=(*crc)^0x1021;
  253.         v=(v<<1)&0x00ff;
  254.     }
  255. }
  256.